<?php

namespace App\Kuafu\CustomerCoupon\Model;

use App\Kuafu\Base\Model\BaseModel;
use App\Kuafu\Base\Model\Traits\KfSoftDeletes;
use App\Kuafu\Base\Model\Traits\KfSplitRelation;
use App\Kuafu\CouponExt\Enum\CouponExtEnum;
use App\Kuafu\User\Exceptions\UserException;
use App\Kuafu\User\Service\AuthService;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Support\Facades\DB;

class CustomerCouponUseHistoryModel extends BaseModel
{
    use KfSoftDeletes, KfSplitRelation;

    protected $table = "customer_coupon_use_history";

    const TYPE_USE    = 1;
    const TYPE_CANCEL = 2;

    const TYPE_MAP = [
        self::TYPE_USE    => "核销",
        self::TYPE_CANCEL => "撤销"
    ];


    /**
     * 优惠券记录写入
     *
     * @param CustomerCouponModel $customerCouponModel
     * @param int $type
     * @param int $shopId
     * @param int $uid
     * @param int $useType
     * @param int $operateTime
     * @return bool
     * @throws UserException
     */
    public static function record(
        CustomerCouponModel $customerCouponModel,
        int $type,
        int $shopId,
        int $uid,
        int $useType = 0,
        int $operateTime = 0,
        string $couponTitle = '',
        int $couponType = 0
    ): bool {
        $createdBy = AuthService::getUserInfo('username', false);
        return self::query()->insert([
            'couponTitle'      => $couponTitle,
            "customerCouponId" => $customerCouponModel->id,
            "couponId"         => $customerCouponModel->couponId,
            "couponCode"       => $customerCouponModel->couponCode,
            "couponFrom"       => CouponExtEnum::EXT_PLATFORM_KUAFU,
            'couponType'       => $couponType,
            "type"             => $type,
            "shopId"           => $shopId,
            "useType"          => $useType,
            "operateTime"      => $operateTime > 0 ? $operateTime : time(),
            "createdAt"        => time(),
            "updatedAt"        => time(),
            "createdBy"        => $createdBy,
            "updatedBy"        => $createdBy,
            "createdByUid"     => $uid,
            "updatedByUid"     => $uid
        ]);
    }

    /**
     * 三方核销 - 优惠券记录写入
     *
     * @param string $orderId
     * @param int $serialNum
     * @param string $couponCode
     * @param string $couponTitle
     * @param int $couponFrom
     * @param int $couponType
     * @param int $couponCostPrice
     * @param int $couponExtDiscountPrice
     * @param int $type
     * @param int $shopId
     * @param int $uid
     * @param string $createdBy
     * @param int $useType
     * @param int $operateTime
     * @return bool
     */
    public static function recordHistory(
        string $orderId,
        int $serialNum,
        string $couponCode,
        string $couponTitle,
        int $couponFrom,
        int $couponType,
        int $couponCostPrice,
        int $couponExtDiscountPrice,
        int $type,
        int $shopId,
        int $uid,
        string $createdBy = '',
        int $useType = 0,
        int $operateTime = 0
    ): bool {
        return self::query()->insert([
            "orderId"                => $orderId,
            "serialNum"              => $serialNum,
            "couponTitle"            => $couponTitle,
            "couponCode"             => $couponCode,
            "couponFrom"             => $couponFrom,
            "couponType"             => $couponType,
            "type"                   => $type,
            "shopId"                 => $shopId,
            "couponCostPrice"        => $couponCostPrice,
            "couponExtDiscountPrice" => $couponExtDiscountPrice,
            "customerCouponId"       => $couponCode,
            "couponId"               => 0,
            "useType"                => $useType,
            "operateTime"            => $operateTime > 0 ? $operateTime : time(),
            "createdAt"              => time(),
            "createdBy"              => $createdBy,
            "updatedBy"              => $createdBy,
            "updatedAt"              => time(),
            "createdByUid"           => $uid,
            "updatedByUid"           => $uid
        ]);
    }

    /**
     * @param int $page
     * @param int $pageSize
     * @param int $shopId
     * @param int $useType
     * @param string $couponCode
     * @param int $operateTimeStart
     * @param int $operateTimeEnd
     * @return LengthAwarePaginator
     */
    public static function getShopCouponUseHistory(
        int $page,
        int $pageSize,
        int $shopId,
        int $useType,
        string $couponCode,
        int $operateTimeStart,
        int $operateTimeEnd,
        int $type,
        int $serialNum,
        string $couponTitle,
        string $orderId,
        int $couponFrom
    ): LengthAwarePaginator {
        return self::query()
                   ->when(strlen($couponCode) > 0, function ($query) use ($couponCode) {
                       $query->where("couponCode", $couponCode);
                   })
                   ->when(strlen($orderId) > 0, function ($query) use ($orderId) {
                       $query->where("orderId", (int)$orderId);
                   })
                   ->when(strlen($couponTitle) > 0, function ($query) use ($couponTitle) {
                       $query->where("couponTitle", 'like', "%" . $couponTitle . "%");
                   })
                   ->when($operateTimeStart > 0, function ($query) use ($operateTimeStart) {
                       $query->where("operateTime", ">", $operateTimeStart);
                   })
                   ->when($operateTimeEnd > 0, function ($query) use ($operateTimeEnd) {
                       $query->where("operateTime", "<", $operateTimeEnd);
                   })
                   ->when($type > 0, function ($query) use ($type) {
                       $query->having("type", $type);
                   })
                   ->when($couponFrom >= 0, function ($query) use ($couponFrom) {
                       $query->where("couponFrom", $couponFrom);
                   })
                   ->when($serialNum > 0, function ($query) use ($serialNum) {
                       $query->where("serialNum", $serialNum);
                   })
                   ->where("shopId", $shopId)
                   ->where("useType", $useType)
                   ->orderBy("id", "desc")
                   ->groupBy("customerCouponId")
                   ->select([
                       "id",
                       "shopId",
                       "customerCouponId",
                       "couponId",
                       "couponCode",
                       "couponType",
                       "couponFrom",
                       "useType",
                       "orderId",
                       "createdBy",
                       "serialNum",
                       "couponTitle",
                       "couponCostPrice",
                       "couponExtDiscountPrice",
                       DB::raw("max(operateTime) as operateTime"),
                       DB::raw("SUBSTRING_INDEX(group_concat(type order by id desc),',',1) as type"),
                   ])
                   ->paginate($pageSize, ['*'], 'pageNum', $page);
    }

    /**
     * @return HasOne
     */
    public function customerCouponRel(): HasOne
    {
        return $this->hasOne(CustomerCouponModel::class, "id", "customerCouponId");
    }
}
